﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo
{
	public class CachedLookupTable
	{
	}
	public class CachedLookupTable<TKey, TValue> : CachedLookupTable, IEnumerable<KeyValuePair<TKey, TValue>>
	{
		public CachedLookupTable(Func<TKey, TValue> createDelegate)
			: this(createDelegate, EqualityComparer<TKey>.Default)
		{
		}
		public CachedLookupTable(Func<TKey, TValue> createDelegate, IEqualityComparer<TKey> comparer)
		{
			ArgumentValidation.CheckNullArgument("createDelegate", createDelegate);
			ArgumentValidation.CheckNullArgument("comparer", comparer);

			this.CreateDelegate = createDelegate;
			this.ItemTable = new Dictionary<TKey, TValue>(comparer);
		}

		public Func<TKey, TValue> CreateDelegate { get; private set; }

		protected Dictionary<TKey, TValue> ItemTable { get; private set; }

		public TValue GetItem(TKey key)
		{
			TValue value;
			bool found;
			lock (this.ItemTable)
			{
				found = this.ItemTable.TryGetValue(key, out value);
			}
			if (!found)
			{
				value = this.CreateDelegate(key);
				lock (this.ItemTable)
				{
					this.ItemTable[key] = value;
				}
			}

			return value;
		}
		public void SetItem(TKey key, TValue value)
		{
			lock (this.ItemTable)
			{
				this.ItemTable[key] = value;
			}
		}

		#region IEnumerable<KeyValuePair<TKey,TValue>> Members

		public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
		{
			return this.ItemTable.GetEnumerator();
		}

		#endregion

		#region IEnumerable Members

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		#endregion
	}
}
